package com.suyx.job.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.suyx.job.entity.JobInfo;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @Auther: lanyanhua
 * @Date: 2018/10/18 0018 11:30
 * @Description: 定时任务帮助类
 */
@Slf4j
@Component
public class SchedulerUtils {

    private Scheduler scheduler;

    @Autowired
    public SchedulerUtils(Scheduler scheduler) {
        this.scheduler = scheduler;
    }


    /**
     * 新增定时任务
     */
    public void addJob(JobInfo jobInfo) throws SchedulerException, IllegalAccessException, InstantiationException, ClassNotFoundException {
        // 启动调度器
        scheduler.start();
        Map<String, Object> param = new HashMap<>();
        param.put("jobInfo", jobInfo);
        JobDataMap newJobDataMap = new JobDataMap(param);
        //构建job信息
        JobDetail jobDetail = JobBuilder.newJob(getClass(jobInfo.getClassPath()))
                .withIdentity(jobInfo.getJobName(), jobInfo.getJobGroup())
                .setJobData(newJobDataMap).build();

        //表达式调度构建器(即任务执行的时间)
        CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(jobInfo.getCronExpression());

        //按新的cronExpression表达式构建一个新的trigger
        CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(jobInfo.getJobName(), jobInfo.getJobGroup())
                .withSchedule(scheduleBuilder).build();
        
         
        if(jobInfo != null && jobInfo.getExecuteType() == 1){
        	SimpleTrigger simpleTrigger = TriggerBuilder.newTrigger()  
                    .withIdentity(jobInfo.getJobName(), jobInfo.getJobGroup())  
                    .startAt(new Date())  
                    .withSchedule(  
                            SimpleScheduleBuilder.simpleSchedule()  
                                    .withIntervalInSeconds(3)  
                                    .withRepeatCount(0))//重复执行的次数，因为加入任务的时候马上执行了，所以不需要重复，否则会多一次。  
                    .build(); 
        	scheduler.scheduleJob(jobDetail, simpleTrigger);
        }else{
        	scheduler.scheduleJob(jobDetail, trigger);
        }
        
    }

    public void updateStatus(JobInfo jobInfo) throws SchedulerException, IllegalAccessException, ClassNotFoundException, InstantiationException {
        scheduler.unscheduleJob(TriggerKey.triggerKey(jobInfo.getJobName(), jobInfo.getJobGroup()));
        if (jobInfo.getJobStatus() == 0) {
            addJob(jobInfo);
        }
    }

    /**
     * 更新定时任务执行时间
     */
    public void jobReschedule(JobInfo jobInfo) throws Exception {
        try {
            TriggerKey triggerKey = TriggerKey.triggerKey(jobInfo.getJobName(), jobInfo.getJobGroup());

            // 修改执行时携带数据
            JobDataMap data = scheduler.getJobDetail(JobKey.jobKey(jobInfo.getJobName(), jobInfo.getJobGroup())).getJobDataMap();
            data.put("jobInfo", jobInfo);
            // 表达式调度构建器
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(jobInfo.getCronExpression());

            CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);

            // 按新的cronExpression表达式重新构建trigger
            trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();

            // 按新的trigger重新设置job执行
            scheduler.rescheduleJob(triggerKey, trigger);
        } catch (SchedulerException e) {
            log.error("更新定时任务失败" +  ExceptionUtils.getStackTrace(e));
            throw new Exception("更新定时任务失败");
        }
    }

    /**
     * 删除定时任务
     */
    public void jobDelete(String jobName, String jobGroupName) throws Exception {
        scheduler.pauseTrigger(TriggerKey.triggerKey(jobName, jobGroupName));
        scheduler.unscheduleJob(TriggerKey.triggerKey(jobName, jobGroupName));
        scheduler.deleteJob(JobKey.jobKey(jobName, jobGroupName));
    }


    private  Class<? extends Job> getClass(String classname) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        Class<?> class1 = Class.forName(classname);
        return ((Job) class1.newInstance()).getClass();
    }


}
